/*
 * Copyright (c) 2021 Huize (Chengdu) Network Technology Co., LTD All rights reserved.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * huize Service Inc
 * All Rights Reserved @2018
 */
package com.huize.zhike.framework.common.result;


import com.huize.zhike.framework.common.enumeration.ErrorEnum;
import com.huize.zhike.framework.common.exception.BizErrorResult;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

/**
 * 描述: Controller返回结构体
 *
 * @author tianyuliang
 * @version $Id: StandardResult.java, v0.1 2019/3/25
 */
@Getter
@SuppressWarnings("unchecked")
public class StandardResult<T> {

    /**
     * 请求成功标识
     */
    public static final String SUCCESS_CODE = "00000";

    /**
     * 调用是否成功
     */
    private boolean success;

    /**
     * 状态码
     */
    private String code;

    /**
     * 状态详细描述
     */
    private String message;

    /**
     * 接口返回的数据
     */
    private T data;

    private StandardResult() {

    }

    public static <T> StandardResult<T> ok() {
        return StandardResult.ok(null);
    }

    public static <T> StandardResult<T> ok(T data) {
        StandardResult result = new StandardResult<T>(); // 必须new新实例，否则每次返回this都是同一个
        result.setSuccess(true).setCode(ErrorEnum.SUCCESS.getCode()).setMessage(ErrorEnum.SUCCESS.getDesc()).setData(data);
        return result;
    }

    public static <T> StandardResult<T> error(BizErrorResult result) {
        return StandardResult.common(false, result.getErrCode(), result.getErrMsg(), null);
    }

    public static <T> StandardResult<T> error(ErrorEnum error) {
        return StandardResult.common(false, error.getCode(), error.getDesc(), null);
    }

    public static <T> StandardResult<T> error(ErrorEnum error, T data) {
        return StandardResult.common(false, error.getCode(), error.getDesc(), data);
    }

    public static <T> StandardResult<T> error(BizErrorResult error, T data) {
        return StandardResult.common(false, error.getErrCode(), error.getErrMsg(), data);
    }

    public static <T> StandardResult<T> error(ErrorEnum error, String message) {
        return StandardResult.common(false, error.getCode(), message, null);
    }

    public static <T> StandardResult<T> error(BizErrorResult error, String message) {
        return StandardResult.common(false, error.getErrCode(), message, null);
    }

    public static <T> StandardResult<T> error(String code, String message) {
        return StandardResult.common(false, code, message, null);
    }

    public static <T> StandardResult<T> common(boolean success, String code, String message) {
        return StandardResult.common(success, code, message, null);
    }

    public static <T> StandardResult<T> common(boolean success, String code, String message, T data) {
        StandardResult result = new StandardResult<T>(); // 必须new新实例，否则每次返回this都是同一个
        result.setSuccess(success).setCode(code).setMessage(message).setData(data);
        return result;
    }

    /**
     * 是否为有效结构体
     *
     * @param other
     * @return 返回false标识无效，true:有效
     */
    public static boolean isValidResult(StandardResult other) {
        if (other == null) {
            return false;
        }
        boolean ok = other.getCode().equals(ErrorEnum.SUCCESS.getCode());
        return ok;
    }

    public StandardResult setSuccess(boolean success) {
        this.success = success;
        return this;
    }

    public StandardResult setCode(String code) {
        this.code = code;
        return this;
    }

    public StandardResult setMessage(String message) {
        this.message = message;
        return this;
    }

    public StandardResult setData(T data) {
        this.data = data;
        return this;
    }

    /**
     * 校验有效返回值
     */
    public boolean checkOK() {
        return StringUtils.isNotBlank(code) && code.trim().equalsIgnoreCase(SUCCESS_CODE);
    }

    /**
     * 校验有效返回值
     */
    public boolean checkFail() {
        return !checkOK();
    }


    @Override
    public String toString() {
        String formatter = "StandardResult{success=%s, code=%d, message=%s, data=%s}";
        return String.format(formatter, isSuccess(), getCode(), getMessage(), getData());
    }

}
